package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.UserHolder;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.exception.BusinessException;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class    MovementsService {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @Autowired
    private MqMessageService mqMessageService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    //发布动态
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
//        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0201","movement",null);
        //1、判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2、获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3、将文件内容上传到阿里云OSS，获取请求地址
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4、将数据封装到Movement对象
        movement.setMedias(medias);
        movement.setUserId(userId);
        //5、调用API完成发布动态
        String movementId = movementApi.publish(movement);
        mqMessageService.sendAudiMessage(movementId);
    }

    //查询个人动态
    public PageResult findByIdMovements(Integer page, Integer pagesize, Long userId) {

//1、根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
        PageResult pr = movementApi.findByUserId(page, pagesize, userId);
        //2、获取PageResult中的item列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        //3、非空判断
        if (items == null) {
            return pr;
        }
        //4、循环数据列表
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> movementsVos = new ArrayList<>();
        for (Movement item : items) {//item为一条动态
            mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",item.getId().toString());
            //5、一个Movement构建一个Vo对象
            MovementsVo movementsVo = MovementsVo.init(userInfo, item);
            movementsVos.add(movementsVo);
        }
        pr.setItems(movementsVos);
//        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",userId.toString());
        //6、构建返回值
        return pr;
    }
    //查看好友动态
    public PageResult findByFriendMovent(Integer page, Integer pagesize) {
//        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",null);
        //获得用户id
        Long userId = UserHolder.getUserId();
        //查询好友动态分析过程
        PageResult pr = movementApi.findByFriendMovementsVo(page, pagesize, userId);
        //2、获取PageResult中的item(动态)列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        return getPageResult(pr, items);

    }

    //方法 (构建前端需要的全部参数 将)
    //修复点赞状态的bug
    private PageResult getPageResult(PageResult pr, List<Movement> items) {
        //3、非空判断
        if (CollUtil.isEmpty(items)) {
            return pr;
        }
        //跟据用户id查时间线表查出所有动态id
        List<MovementsVo> movementsVos = new ArrayList<>();
        for (Movement item : items) {
            Long id = item.getUserId();
            //根据动态中的用户id查出用户信息
            UserInfo userInfo = userInfoApi.findById(id);
            //拼接成movenentsVo
            MovementsVo movementsVo = MovementsVo.init(userInfo, item);
            movementsVo.setLoveCount(item.getLoveCount());
            movementsVo.setLikeCount(item.getLikeCount());
            movementsVo.setCommentCount(item.getCommentCount());
            String key = Constants.MOVEMENTS_INTERACT_KEY + item.getId().toHexString();
            String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
            String loveHashKey =Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
            if(redisTemplate.opsForHash().hasKey(key, hashKey)){
                movementsVo.setHasLiked(1);
            }
            if(redisTemplate.opsForHash().hasKey(key, loveHashKey)){
                movementsVo.setHasLoved(1);
            }
            //修复点赞状态的bug  判断hashKey 是否存在

            movementsVos.add(movementsVo);
        }
        //拼接成movenentsVo
        pr.setItems(movementsVos);
        return pr;
    }
     //查看推荐动态
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
//        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",null);
        //从redis中获得数据
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        //判断数据是否存在
        PageResult pageResult =new PageResult();
        if (StringUtils.isEmpty(redisValue)) {
            PageResult pr = movementApi.randomMovements(page,pagesize);
            List<Movement> items = (List<Movement>)pr.getItems();
             pageResult = getPageResult(pr, items);
            //如果不存在，调用api随机获得10条动态数据
        } else {
            //如果存在，处理pid数据
            String[] values = redisValue.split(",");
            //判断当前页的起始条数是否小于数组总数
            if ((page - 1) * pagesize < values.length) {
                //获得需要查询的pid
                List<Long> pids = Arrays.stream(values).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e))
                        .collect(Collectors.toList());
                //调用api根据pid数组查询动态数据
                PageResult pr=movementApi.findMovementsByPids(pids,page,pagesize);
                List<Movement> items = (List<Movement>)pr.getItems();
                 pageResult = getPageResult(pr, items);
            }
        }
         return pageResult;
        //调用公共方法构造返回值
    }

  //查看个人动态
    public MovementsVo findById(String movementId) {

            Movement movement=movementApi.findById(movementId);
        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",movement.getId().toString());
            if(movement!=null){
                Long userId = movement.getUserId();
                UserInfo userInfo = userInfoApi.findById(userId);
                return MovementsVo.init(userInfo,movement);
            }else {
                return null;
            }
    }
   //查看访客记录
    public List<VisitorsVo> findByVisitors() {
        Long userId = UserHolder.getUserId();
        String key=Constants.VISITORS;
        String hashKey=userId.toString();
      String  value= (String)redisTemplate.opsForHash().get(key, hashKey);
      //获得用户查看访客的时间
      Long Date=StringUtils.isEmpty(value)? null:Long.valueOf(value);
      //查出访客记录
      List<Visitors> list=visitorsApi.findVisitors(userId,Date);
        List<Long> visitorUserIds = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        //查询用户数据
        Map<Long, UserInfo> map = userInfoApi.findByIds(visitorUserIds, null, null);
        List<VisitorsVo> vos=new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            if(userId!=null){
                VisitorsVo init = VisitorsVo.init(userInfo, visitors);
                vos.add(init);
            }
        }
        return vos;

    }
}